using System;
using System.Collections.Generic;
using System.Configuration;
using System.Text.RegularExpressions;
using System.Xml;

namespace Poka_Yoke.Analysis
{
    public class Configuration : IConfigurationSectionHandler
    {
        private string _searchPattern;

        public string SearchPattern
        {
            get
            {
                return _searchPattern;
            }
        }

        private List<Rule> _rulesCollection;

        public List<Rule> RulesCollection
        {
            get
            {
                return _rulesCollection;        
            }
        }

        public Configuration(string searchExtension, List<Rule> rulesCollection)
        {
            if (string.IsNullOrEmpty(searchExtension))
            {
                throw new ArgumentNullException("searchExtension");
            }

            if (rulesCollection == null)
            {
                throw new ArgumentNullException("ruleCollection");
            }

            _searchPattern = searchExtension;
            _rulesCollection = rulesCollection;
        }

        public object Create(object parent, object configContext, XmlNode section)
        {
            XmlNode searchExtension  = section.SelectSingleNode("SearchPattern");

            if (searchExtension == null || string.IsNullOrEmpty(searchExtension.InnerText))
            {
                throw new ConfigurationErrorsException(AnalyserMessages.SearchPatternConfigurationMissing);
            }

            List<Rule> rules = new List<Rule>();

            XmlNodeList ruleList = section.SelectNodes("Rules/Rule");

            foreach(XmlNode ruleNode in ruleList)
            {
                XmlNode message = ruleNode.SelectSingleNode("Message");

                if (message == null || string.IsNullOrEmpty(message.InnerText))
                {
                    throw new ConfigurationErrorsException(AnalyserMessages.NoMessageForRule);
                }

                XmlNode description = ruleNode.SelectSingleNode("Description");

                if (description == null || string.IsNullOrEmpty(description.InnerText))
                {
                    throw new ConfigurationErrorsException(AnalyserMessages.NoDescriptionForRule);
                }

                XmlNode severity = ruleNode.SelectSingleNode("Severity");

                if (severity == null || !Enum.IsDefined(typeof(Severity), severity.InnerText))
                {
                    throw new ConfigurationErrorsException(AnalyserMessages.SeverityNotRecognised);
                }

                XmlNode regex = ruleNode.SelectSingleNode("Pattern");

                if (regex == null || string.IsNullOrEmpty(regex.InnerText))
                {
                    throw new ConfigurationErrorsException(AnalyserMessages.NoPatternForRule);
                }

                Regex ruleRegex = new Regex(regex.InnerText, RegexOptions.Compiled);

                Rule rule = new Rule(message.InnerText, description.InnerText, (Severity) Enum.Parse(typeof(Severity), severity.InnerText), ruleRegex);

                rules.Add(rule);
            }

            return new Configuration(searchExtension.InnerText, rules);
        }
    }
}
